package es.cazadoresmadridejos.beans.controller.partner;

import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.security.authentication.encoding.PasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.servlet.ModelAndView;

import es.cazadoresmadridejos.beans.manager.city.CityManager;
import es.cazadoresmadridejos.beans.manager.partner.PartnerManager;
import es.cazadoresmadridejos.beans.manager.province.ProvinceManager;
import es.cazadoresmadridejos.beans.manager.reason.ReasonManager;
import es.cazadoresmadridejos.beans.manager.session.UserPreferences;
import es.cazadoresmadridejos.beans.validator.partner.PartnerValidator;
import es.cazadoresmadridejos.model.City;
import es.cazadoresmadridejos.model.Partner;
import es.cazadoresmadridejos.model.Partner.HunterType;
import es.cazadoresmadridejos.model.Partner.Role;
import es.cazadoresmadridejos.model.Partner.Sex;
import es.cazadoresmadridejos.model.Province;
import es.cazadoresmadridejos.objs.security.User;
import es.cazadoresmadridejos.propertyeditor.PartnerPropertyEditor;
import es.cazadoresmadridejos.util.FileUtils;
import es.cazadoresmadridejos.util.constants.Constants;
import es.cazadoresmadridejos.util.model.ReasonUtil;
import es.cazadoresmadridejos.util.validation.ValidationContainer;
import es.cazadoresmadridejos.web.util.ListUtil;


@Controller
public class PartnerCreateModifyController {

	@Autowired private PartnerManager partnerManager;
	@Autowired private ProvinceManager provinceManager;
	@Autowired private CityManager cityManager;
	@Autowired private PartnerValidator partnerValidator;
	@Autowired(required=false) private UserPreferences userPreferences;
	@Autowired private ReasonManager reasonManager;
	@Autowired private PasswordEncoder passwordEncoder;

	@InitBinder
	public void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Throwable{
		binder.registerCustomEditor(Partner.class, new PartnerPropertyEditor(partnerManager));

		binder.registerCustomEditor(Date.class, "birthDate",new CustomDateEditor(Constants.sdf,true));
	}

	@RequestMapping(value="/partnerCreateModify.html",method=RequestMethod.GET)
	public ModelAndView createModify(
			@RequestParam(value="id",required=false) Partner partner) throws Throwable {
		ModelAndView mv = new ModelAndView();
		if(partner == null){
			partner = new Partner();
			partner.init();
			mv.addObject("type","create");
		}else{
			mv.addObject("type","update");
		}
		mv.addObject("partner",partner);
		mv.addObject("sexValues",ListUtil.toString(Sex.values()));
		mv.addObject("roles",ListUtil.toString(Role.values()));
		List<Province> provinces = provinceManager.findAll();
		List<City> cities= cityManager.findByProvince(partner.getCity().getProvince().getId());

		Partner loggedPartner = userPreferences.getPartner();

		mv.addObject("provinces", provinces);
		mv.addObject("cities", cities);
		mv.addObject("hunterTypes", HunterType.values());
		mv.addObject("loggedPartner", Role.ADMINISTRADOR.equals(loggedPartner.getRole()));

		String string = partnerManager.findAllForAutocompleteBigGame(partner.getId());
		mv.addObject("partners",string);		

		return mv;
	}
	@RequestMapping(value="/partnerCreateModify.html",method=RequestMethod.POST)
	public ModelAndView submit(
			@ModelAttribute("partner") Partner partner, 
			BindingResult result, 
			SessionStatus status,
			HttpServletRequest request
			) throws Throwable {

		ModelAndView mv = new ModelAndView("redirect:index.html");
		if(partner.getId() != null){
			Partner oldPartner = partnerManager.get(partner.getId());

			//Si el password es nulo es porque el administrador esta modificando un usuario y no quiere cambiarle su contrasena
			if(StringUtils.isBlank(partner.getPassword()) && oldPartner != null){
				partner.setPassword(oldPartner.getPassword());
			}else{
				partner.setPassword(passwordEncoder.encodePassword(partner.getPassword(), User.getSalt()));
			}

			//Si modifica el administrador no se toca lafoto
			if(!userPreferences.getPartner().getId().equals(oldPartner.getId())){
				partner.setImage(oldPartner.getImage());
				mv.addObject("screen", "partnerList.html");
			}else{
				if(partner.getFile() != null && !partner.getFile().isEmpty()){
					partner.setImage(FileUtils.saveAvatar(partner.getFile(),partner.getId()));
					Thread.sleep(1000);
				}
			}
		}

		if(partner.getPartner() != null &&partner.getPartner().getId() == null){
			partner.setPartner(null);
		}else{
			if(partner.getPartner().getId() != null){
				partner.setPartner(partnerManager.get(partner.getPartner().getId()));
				partner.getPartner().setPartner(partner);
			}
		}

		List<ValidationContainer> errors = partnerValidator.validate(partner);
		if(errors.isEmpty()){
			mv.addObject("okMessage", "THE_PROCESS_FINISHED_SUCCESSFULLY");
		}else{
			mv.addObject("errors",errors);
		}

		if(partner.getActive() == null){
			partner.setActive(1);
		}
		if(partner.getRole() == null){
			partner.setRole(Role.CAZADOR);
		}
		partner.initValues();
		//Si no tiene ninguna temporada seleccionada se le pone la actual
		if(partner.getSelectedReason() == null || partner.getSelectedReason().getId() == null){
			partner.setSelectedReason(reasonManager.getByReason(ReasonUtil.getCurrentReason()));
		}
		partnerManager.save(partner);

		return mv;
	}
}
